/**
 * outsider.com.cn Inc.
 * Copyright (c) 2011-2022 All Rights Reserved.
 */
package com.yuanmeng.common.core.handler;

import java.math.BigDecimal;

import com.yuanmeng.common.core.domain.PointCreditDTO;

/**
 * @author outsider
 * @version Id: ProductPriceCalculateHandler.java, v 0.1 2022/9/15 17:49 outsider Exp $$
 */
public class ProductPriceCalculateHandler {
    /**
     * 会员等级优惠比例
     */
    private static final BigDecimal price             = new BigDecimal("100");

    /**
     * 分销金额比例 70%
     */
    private static final BigDecimal DISTRIBUTION_RATE = new BigDecimal("0.70");

    /**
     * 计算商品会员等级优惠金额
     * @param totalAmount       商品总金额
     * @param totalCostAmount   商品成本总金额
     * @param discountRate      会员等级折扣率
     * @return
     */
    public static BigDecimal calculateMemberLevelOffersAmount(BigDecimal totalAmount,
                                                              BigDecimal totalCostAmount,
                                                              BigDecimal discountRate) {
        if (null != totalAmount && null != totalCostAmount
            && discountRate.compareTo(BigDecimal.ZERO) > 0) {
            BigDecimal grossPrice = totalAmount.subtract(totalCostAmount);
            if (grossPrice.compareTo(BigDecimal.ZERO) > 0) {
                return grossPrice.multiply(DISTRIBUTION_RATE)
                    .multiply(BigDecimal.valueOf(1)
                        .subtract(discountRate.divide(price, 2, BigDecimal.ROUND_HALF_UP)))
                    .setScale(2, BigDecimal.ROUND_HALF_UP);
            }
        }
        return BigDecimal.ZERO;
    }

    /**
     * 计算折扣券优惠金额
     * @param totalAmount       商品总金额
     * @param conditionAmount   满多少可使用
     * @param benefitDiscount   优惠折扣
     * @return
     */
    public static BigDecimal calculateDiscountCouponAmount(BigDecimal totalAmount,
                                                           BigDecimal conditionAmount,
                                                           BigDecimal benefitDiscount) {
        Boolean flag = calculateCouponUserStatus(totalAmount, conditionAmount);
        if (flag) {
            return totalAmount.multiply(benefitDiscount.divide(price, 2, BigDecimal.ROUND_HALF_UP));
        }
        return BigDecimal.ZERO;
    }

    /**
     * 判断当前金额是否满足优惠券使用条件
     * @param totalAmount
     * @param conditionAmount
     * @return
     */
    public static Boolean calculateCouponUserStatus(BigDecimal totalAmount,
                                                    BigDecimal conditionAmount) {
        if (totalAmount.compareTo(conditionAmount) == -1) {
            return false;
        }
        return true;
    }

    /**
     * 计算积分抵扣金额
     * @param grossProfit       毛利润
     * @param pointDiscount     积分抵扣比例
     * @param pointPrice        积分价值
     * @param existPointNum     现有积分数量
     * @return
     */
    public static PointCreditDTO pointCreditAmount(BigDecimal grossProfit, BigDecimal pointDiscount,
                                                   BigDecimal pointPrice, BigDecimal existPointNum,
                                                   PointCreditDTO creditDTO) {
        if (null != grossProfit && null != pointDiscount) {
            // 可使用积分抵扣金额
            BigDecimal pointCreditAmount = grossProfit
                .multiply(pointDiscount.divide(price, 2, BigDecimal.ROUND_HALF_UP));
            if (pointCreditAmount.compareTo(pointPrice) != -1) {
                // 积分抵扣数量
                BigDecimal pointNum = pointCreditAmount.divide(pointPrice, 0,
                    BigDecimal.ROUND_DOWN);
                creditDTO.setPointNum(BigDecimal.ZERO);
                creditDTO.setPointAmount(BigDecimal.ZERO);
                if (existPointNum.compareTo(BigDecimal.ZERO) == 1) {
                    if (existPointNum.compareTo(pointNum) == 1) {
                        creditDTO.setPointNum(pointNum);
                        creditDTO.setPointAmount(pointPrice.multiply(pointNum));
                    } else {
                        creditDTO.setPointNum(existPointNum);
                        creditDTO.setPointAmount(pointPrice.multiply(existPointNum));
                    }
                }
            }
        }
        return creditDTO;
    }

    /**
     * 计算折扣优惠金额
     * @param benefitDiscount
     * @param totalAmount
     * @return
     */
    public static BigDecimal calculateOffersAmount(BigDecimal benefitDiscount,
                                                   BigDecimal totalAmount) {
        return totalAmount.multiply(benefitDiscount.divide(price, 2, BigDecimal.ROUND_HALF_UP));
    }

    /**
     * 按数量计算运费金额
     * @param productUnit                   商品数量
     * @param defaultFirstUnit              默认首件件数
     * @param defaultNextUnit               续件件数
     * @param defaultFirstPrice             默认首重/件金额
     * @param defaultNextPrice              默认续重/件金额
     * @return
     */
    public static BigDecimal calculateFreightAmountByNum(Long productUnit, Long defaultFirstUnit,
                                                         Long defaultNextUnit,
                                                         BigDecimal defaultFirstPrice,
                                                         BigDecimal defaultNextPrice) {
        if (productUnit < defaultFirstUnit) {
            return defaultFirstPrice;
        } else {
            BigDecimal unit = BigDecimal.valueOf(productUnit - defaultFirstUnit)
                .divide(BigDecimal.valueOf(defaultNextUnit), 2, BigDecimal.ROUND_HALF_UP);

            return defaultNextPrice.multiply(unit);
        }
    }

    /**
     * 按重量计算运费金额
     * @param productWeight                   商品重量
     * @param defaultFirstWeight              默认首重
     * @param defaultNextWeight               续重
     * @param defaultFirstPrice             默认首重/件金额
     * @param defaultNextPrice              默认续重/件金额
     * @return
     */
    public static BigDecimal calculateFreightAmountByWeight(BigDecimal productWeight,
                                                            BigDecimal defaultFirstWeight,
                                                            BigDecimal defaultNextWeight,
                                                            BigDecimal defaultFirstPrice,
                                                            BigDecimal defaultNextPrice) {
        if (defaultFirstWeight.compareTo(productWeight) == 1) {
            return defaultFirstPrice;
        } else {
            BigDecimal weight = productWeight.subtract(defaultFirstWeight).divide(defaultNextWeight,
                2, BigDecimal.ROUND_HALF_UP);

            return defaultNextPrice.multiply(weight);
        }
    }

    /**
     * 计算订单商品分别优惠金额
     * @param offerTotalAmount      优惠总金额
     * @param productTotalAmount    商品总金额
     * @param productAmount         单个规格商品总金额
     * @return
     */
    public static BigDecimal calculateOrderProductOfferAmount(BigDecimal offerTotalAmount,
                                                              BigDecimal productTotalAmount,
                                                              BigDecimal productAmount) {
        if (offerTotalAmount.compareTo(BigDecimal.ZERO) != 1) {
            return BigDecimal.ZERO;
        }

        return offerTotalAmount.multiply(productAmount).divide(productTotalAmount, 2,
            BigDecimal.ROUND_HALF_DOWN);
    }

    /**
     * 计算订单商品积分抵扣数量
     * @param pointTotalNum      优惠总金额
     * @param productTotalAmount    商品总金额
     * @param productAmount         单个规格商品总金额
     * @return
     */
    public static BigDecimal calculateOrderProductOfferPoint(BigDecimal pointTotalNum,
                                                             BigDecimal productTotalAmount,
                                                             BigDecimal productAmount) {
        if (pointTotalNum.compareTo(BigDecimal.ZERO) < 1) {
            return BigDecimal.ZERO;
        }

        return pointTotalNum.multiply(productAmount).divide(productTotalAmount, 0,
            BigDecimal.ROUND_HALF_DOWN);
    }

    /**
     * 计算分销收益
     * @param grossProfit               毛利润
     * @param distributionLevelRate     分销等级比例
     * @return
     */
    public static BigDecimal calculateDistributeAmount(BigDecimal grossProfit,
                                                       BigDecimal distributionLevelRate) {
        return grossProfit.multiply(DISTRIBUTION_RATE)
            .multiply((distributionLevelRate.divide(price))).setScale(2, BigDecimal.ROUND_HALF_UP);
    }

    /**
     * 计算用户提现手续费
     * @param withdrawalAmount
     * @param withdrawalFee
     * @return
     */
    public static BigDecimal calculateWithdrawalFee(BigDecimal withdrawalAmount,
                                                    int withdrawalFee) {
        return withdrawalAmount.multiply((BigDecimal.valueOf(withdrawalFee)).divide(price))
            .setScale(2, BigDecimal.ROUND_HALF_UP);
    }
}